package com.animo.list.ext;

import com.animo.list.ext.impl.ExtArrayList;

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @author 刘金泳
 * @Date 2020/7/29
 */
public class ArrayListTest {

    /**
     * java.util.ConcurrentModificationException
     *
     * 此段代码操作为 多线程环境下对ArrayList进行读写导致ConcurrentModificationException
     *
     * 这也是ArrayList的fail-fast的一种机制 在add、remove方法内有一个全局变量modCount进行了++
     *
     * printAll方法中使用了ArrayList内部的forEach
     *
     * 内部代码有两个点
     *
     * final int expectedModCount = modCount; 把对列表操作次数赋值
     *
     * if (modCount != expectedModCount) {
     *       throw new ConcurrentModificationException();
     *    }
     *  在多线程（同步）操作下 如果A线程打印是 modCount = 1，则expectedModCount = 1
     *
     *  但是这时候还没有进入判断的情况下 B线程add了一下 所以modCount = 2 然后 2 != 1
     *
     *  也就是A线程打印的时候 B线程在添加 这时候modCount的值就被修改了这种情况会导致ConcurrentModificationException
     *
     */

    private List<String> integers = new ArrayList<>();

    public static void main(String[] args) throws InterruptedException {
        ArrayListTest arrayListTest = new ArrayListTest();
        arrayListTest.start();
    }

    public void start (){
        new Thread(new ThreadOne()).start();
        new Thread(new ThreadTwo()).start();
    }

    public void printAll() {
        integers.forEach((e) ->{});
    }

    class ThreadOne implements Runnable{

        @Override
        public void run() {
            for (int i = 0; i < 10; ++i) {
                integers.add(i + "");
                printAll();
            }
        }
    }

    class ThreadTwo implements Runnable{

        @Override
        public void run() {
            for (int i = 10; i < 20; ++i) {
                integers.add(i + "");
                printAll();
            }
        }
    }

}
